package com.Sdebruijn.curriculumvitae.db;

import android.content.Context;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;

import com.Sdebruijn.curriculumvitae.models.App;
import com.Sdebruijn.curriculumvitae.models.Applicant;
import com.Sdebruijn.curriculumvitae.models.Course;
import com.Sdebruijn.curriculumvitae.models.Education;
import com.Sdebruijn.curriculumvitae.models.Experience;
import com.Sdebruijn.curriculumvitae.models.Hobby;
import com.Sdebruijn.curriculumvitae.models.Institution;
import com.Sdebruijn.curriculumvitae.models.Lesson;
import com.Sdebruijn.curriculumvitae.models.OnlinePerson;
import com.Sdebruijn.curriculumvitae.models.Person;
import com.Sdebruijn.curriculumvitae.models.Reference;
import com.Sdebruijn.curriculumvitae.models.Work;
import com.Sdebruijn.curriculumvitae.models.WorkTask;
import com.j256.ormlite.android.apptools.OrmLiteSqliteOpenHelper;
import com.j256.ormlite.dao.Dao;
import com.j256.ormlite.dao.DaoManager;
import com.j256.ormlite.support.ConnectionSource;
import com.j256.ormlite.table.TableUtils;

/**
 * Utility class for managing the ORMLite-SQLite database
 * 
 * @author Stefan de Bruijn
 */
public class DatabaseHelper extends OrmLiteSqliteOpenHelper {

	/**
	 * The database name. It will be saved on the device like this.
	 */
	private static final String DATABASE_NAME = "curriculumvitae.sqlite";

	/**
	 * Version used to check whether the database should call {@code OnUpgrade}
	 */
	private static final int DATABASE_VERSION = 1;

	/*
	 * The DAO objects we use to access the SimpleData tables
	 */
	private Dao<Person, Integer> applicantDao = null;
	private Dao<OnlinePerson, Integer> onlinePersonDao = null;
	private Dao<App, Integer> appDao = null;
	private Dao<Hobby, Integer> hobbyDao = null;
	private Dao<Course, Integer> courseDao = null;

	private Dao<Experience, Integer> educationDao = null;

	private Dao<Experience, Integer> workDao = null;

	private Dao<Institution, Integer> institutionDao = null;
	private Dao<WorkTask, Integer> workTaskDao = null;

	private Dao<Lesson, Integer> lessonDao = null;
	//private Dao<Reference, Integer> referenceDao = null;

	public DatabaseHelper(Context context) {
		super(context, DATABASE_NAME, null, DATABASE_VERSION);
	}

	@Override
	public void onCreate(SQLiteDatabase database, ConnectionSource connectionSource) {
		try {

			// Create our Dao objects
			applicantDao = DaoManager.createDao(connectionSource, Applicant.class);
			appDao = DaoManager.createDao(connectionSource, App.class);
			hobbyDao = DaoManager.createDao(connectionSource, Hobby.class);
			courseDao = DaoManager.createDao(connectionSource, Course.class);
			educationDao = DaoManager.createDao(connectionSource, Education.class);
			workDao = DaoManager.createDao(connectionSource, Work.class);
			workTaskDao = DaoManager.createDao(getConnectionSource(), WorkTask.class);
			onlinePersonDao = DaoManager.createDao(connectionSource, OnlinePerson.class);
			institutionDao = DaoManager.createDao(connectionSource, Institution.class);
			lessonDao = DaoManager.createDao(connectionSource, Lesson.class);

			// Create our database tables
			TableUtils.createTable(connectionSource, Applicant.class);
			TableUtils.createTable(connectionSource, App.class);
			TableUtils.createTable(connectionSource, Hobby.class);
			TableUtils.createTable(connectionSource, Course.class);
			TableUtils.createTable(connectionSource, Education.class);
			TableUtils.createTable(connectionSource, Work.class);
			TableUtils.createTable(connectionSource, Institution.class);
			TableUtils.createTable(connectionSource, Lesson.class);
			TableUtils.createTable(connectionSource, OnlinePerson.class);
			TableUtils.createTable(connectionSource, Reference.class);
			TableUtils.createTable(connectionSource, WorkTask.class);

		} catch (SQLException e) {
			Log.e(DatabaseHelper.class.getName(), "Can't create database", e);
			throw new RuntimeException(e);
		} catch (java.sql.SQLException e) {
			e.printStackTrace();
		}

	}

	@Override
	public void onUpgrade(SQLiteDatabase db, ConnectionSource connectionSource, int oldVersion,
			int newVersion) {
		// If we have a new database version, we just drop everything and
		// re-build. Could possibly use the same set-up to actually update the
		// database, but does not seem worth the trouble and complication here
		try {
			switch (oldVersion) {
			case 1:
				TableUtils.dropTable(connectionSource, Applicant.class, true);
				TableUtils.dropTable(connectionSource, App.class, true);
				TableUtils.dropTable(connectionSource, Hobby.class, true);
				TableUtils.dropTable(connectionSource, Course.class, true);
				TableUtils.dropTable(connectionSource, Education.class, true);
				TableUtils.dropTable(connectionSource, Work.class, true);
				TableUtils.dropTable(connectionSource, Institution.class, true);
				TableUtils.dropTable(connectionSource, Lesson.class, true);
				TableUtils.dropTable(connectionSource, OnlinePerson.class, true);
				TableUtils.dropTable(connectionSource, WorkTask.class, true);

				onCreate(db, connectionSource);
			}
		} catch (SQLException e) {
			Log.e(DatabaseHelper.class.getName(), "exception during onUpgrade", e);
			throw new RuntimeException(e);
		} catch (java.sql.SQLException e) {
			e.printStackTrace();
		}

	}

	public Dao<Person, Integer> getApplicantDao() {
		if (null == applicantDao) {
			try {
				applicantDao = getDao(Applicant.class);
			} catch (java.sql.SQLException e) {
				e.printStackTrace();
			}
		}
		return applicantDao;
	}

	public Dao<App, Integer> getAppDao() {
		if (null == appDao) {
			try {
				appDao = getDao(App.class);
			} catch (java.sql.SQLException e) {
				e.printStackTrace();
			}
		}
		return appDao;
	}

	public Dao<Course, Integer> getCourseDao() {
		if (null == courseDao) {
			try {
				courseDao = getDao(Course.class);
			} catch (java.sql.SQLException e) {
				e.printStackTrace();
			}
		}
		return courseDao;
	}

	public Dao<Hobby, Integer> getHobbyDao() {
		if (null == hobbyDao) {
			try {
				hobbyDao = getDao(Hobby.class);
			} catch (java.sql.SQLException e) {
				e.printStackTrace();
			}
		}
		return hobbyDao;
	}

	public Dao<Experience, Integer> getEducationDao() {
		if (null == educationDao) {
			try {
				educationDao = getDao(Education.class);
			} catch (java.sql.SQLException e) {
				e.printStackTrace();
			}
		}
		return educationDao;
	}

	public Dao<Experience, Integer> getWorkDao() {
		if (null == workDao) {
			try {
				workDao = getDao(Work.class);
			} catch (java.sql.SQLException e) {
				e.printStackTrace();
			}
		}
		return workDao;
	}

	public Dao<OnlinePerson, Integer> getOnlinePersonDao() {
		if (null == onlinePersonDao) {
			try {
				onlinePersonDao = getDao(OnlinePerson.class);
			} catch (java.sql.SQLException e) {
				e.printStackTrace();
			}
		}
		return onlinePersonDao;
	}

	public Dao<Institution, Integer> getInstitutionDao() {
		if (null == institutionDao) {
			try {
				institutionDao = getDao(Institution.class);
			} catch (java.sql.SQLException e) {
				e.printStackTrace();
			}
		}
		return institutionDao;
	}

	public Dao<WorkTask, Integer> getWorkTaskDao() {
		if (null == workTaskDao) {
			try {
				workTaskDao = getDao(WorkTask.class);
			} catch (java.sql.SQLException e) {
				e.printStackTrace();
			}
		}
		return workTaskDao;
	}

	public Dao<Lesson, Integer> getLessonDao() {
		if (null == lessonDao) {
			try {
				lessonDao = getDao(Lesson.class);
			} catch (java.sql.SQLException e) {
				e.printStackTrace();
			}
		}
		return lessonDao;
	}

}
